#include <iostream>

#include "helpers.h"
#include "simple_validator.h"

using namespace std;

const string SimpleValidator::mapping [] = {
    "Correct", "Variables bad format", "Signs bad format",
    "Unrecognized character", "Empty equation", "Other Error"};

SimpleValidator::FormatCodeValue SimpleValidator::DoValidation() {
  if (CheckEmptyEquation())
    return EmptyEquation;
  if (CheckUnrecognizedCharacter())
    return UnrecognizedCharacter;
  if (CheckNumberOrVariableBadFormat())
    return NumberOrVariableBadFormat;
  if (CheckSignsBadFormat())
    return SignsBadFormat;

  return Correct;
}

bool SimpleValidator::CheckEmptyEquation() {
  return equation_ == "";
}

bool SimpleValidator::CheckUnrecognizedCharacter(){
  set<char> allowed_characters;
  allowed_characters.insert('+');
  allowed_characters.insert('*');
  allowed_characters.insert(' ');
  allowed_characters.insert('=');
  allowed_characters.insert('.');
  for (int i = 0; i < (int)equation_.size(); ++i) {
    if (!isalnum(equation_[i])
        && allowed_characters.find(equation_[i]) == allowed_characters.end()) 
      return true;
  }  

  return false;
}

bool SimpleValidator::CheckNumberOrVariableBadFormat() {
  vector<string> auxiliar = SplitByDelimiter(equation_, "=");
  vector<string> tokens = SplitByDelimiter(auxiliar[0], "+");
  for (int i = 0; i < (int)tokens.size(); ++i) {
    if (tokens[i] == "+" or tokens[i] == "*") {
      if (!(i&1)) return true;
      continue;
    }
    vector<string> terms = SplitByDelimiter(tokens[i], "*");
    if (terms.size() == 1) {
      if (IsANumber(terms[0])) return true;
      if (!IsAVariable(terms[0])) return true;
      continue;
    }
    if (Strim(terms[1]) != "*") return true;
    if (IsANumber(terms[0]) && IsAVariable(terms[2]));
    else if (IsANumber(terms[2]) && IsAVariable(terms[0]));
    else return true;
  }  
  return false;
}

bool SimpleValidator::CheckSignsBadFormat() {
  vector<string> auxiliar = SplitByDelimiter(equation_, "=");
  if (auxiliar.size() != 3) return true;
  vector<string> tokens = SplitByDelimiter(equation_, "+*");
  if (!(tokens.size()&1))
    return true;
  for (int i = 0; i < (int)tokens.size(); ++i) {
    if (tokens[i] != "+" && tokens[i] != "*") {
      if (i&1)
        return true;
    } else if (!(i&1)) return true;
  } 
  return false;
}
